/*
 * Justin Prentice
 * TCSS 305
 * Tetris gui - Board View
 */

package view;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.util.List;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JPanel;

import model.Block;

/**
 * A class to display the main tetris board.  
 * @author Justin Prentice
 * @version 1.0
 */
@SuppressWarnings("serial")
public class BoardView extends JPanel implements Observer
{
  /**
   * The number of blocks per row in a standarda tetris game.
   */
  private static final int BLOCKS_PER_ROW = 10;
  
  /**
   * The preferred size of the board view.
   */
  private static final Dimension PREFERRED_SIZE = new Dimension(300, 600);
  
  /**
   * The current state of the board.
   */
  private TetrisUpdate my_update;
  
  /**
   * A color interpreter for deciding what colors to use for blocks.
   */
  private final ColorInterpreter my_colorer;
  
  /**
   * Whether game game is paused or not.
   */
  private boolean my_pause_state;
  
  /**
   * Constructs a panel for viewing the game board.  
   * @param the_interpreter the color interpreter for choosing block colors.
   */
  public BoardView(final ColorInterpreter the_interpreter)
  {
    super();
    setBackground(Color.black);
    setPreferredSize(PREFERRED_SIZE);
    my_colorer = the_interpreter;
  }
  
  @Override
  public void update(final Observable the_observed, final Object the_update)
  {
    my_update = (TetrisUpdate) the_update;
    repaint();
  }
  
  @Override
  public void paintComponent(final Graphics the_graphics) 
  {
    super.paintComponent(the_graphics);
    final Graphics2D g2d = (Graphics2D) the_graphics;
    
    if (my_update != null && !my_pause_state)
    {
      
      final List<Block[]> blocks = ((TetrisUpdate) my_update).getBlocks();
      
      final int blocksize = Math.min(getWidth(), getHeight() / 2) / BLOCKS_PER_ROW;
      
      //draws frozen pieces.
      for (int i = 0; i < blocks.size(); i++)
      {
        for (int j = 0; j < blocks.get(i).length; j++)
        {
          if (blocks.get(i)[j] != Block.EMPTY)
          {
            g2d.setColor(my_colorer.interpretColor(blocks.get(i)[j]));
            g2d.draw3DRect(blocksize * j + //next line is leftover width in case of resize
                           Math.max(getWidth() - blocksize * BLOCKS_PER_ROW, 0) / 2 , 
                           getHeight() - blocksize * i - blocksize, 
                           blocksize, blocksize, true);
          }
        }
      }
      
      //draws piece in progress
      final int[][] coordinates = my_update.getPiece().getBoardCoordinates();
      g2d.setColor(my_colorer.interpretColor(my_update.getPiece().getBlock()));
      for (int i = 0; i < coordinates.length; i++)
      {
        if (coordinates[i][1] < BLOCKS_PER_ROW * 2) //prevents drawing pieces above the board.
        {
          g2d.draw3DRect(blocksize * coordinates[i][0] + 
                         Math.max(getWidth() - blocksize * BLOCKS_PER_ROW, 0) / 2, 
                         getHeight() - blocksize * coordinates[i][1] - blocksize, 
                         blocksize, blocksize, true);
        } 
      }
      
      //draws enclosing rectangle, if not in even aspect ratio
      g2d.setColor(Color.darkGray);
      g2d.draw3DRect(Math.max(getWidth() - blocksize * BLOCKS_PER_ROW, 0) / 2, 
                     Math.max(getHeight() - blocksize * BLOCKS_PER_ROW * 2, 0), 
                     BLOCKS_PER_ROW * blocksize, 
                     BLOCKS_PER_ROW * blocksize * 2, true);
      
    }
    if (my_pause_state)
    {
      g2d.setColor(Color.lightGray);
      g2d.drawString("Paused", getWidth() / 2, getHeight() / 2);
    }
  }
  
  /**
   * Sets the game to be paused or not.
   * @param the_pause_state true if paused, false otherwise
   */
  public void setPaused(final boolean the_pause_state)
  {
    my_pause_state = the_pause_state;
  }
  
}
